import os
import pandas as pd
from PyQt5.QtCore import QThread, pyqtSignal


class DataProcessor(QThread):
    """数据处理线程，避免UI卡顿，使用列标进行字段处理"""
    progress_updated = pyqtSignal(int)
    log_updated = pyqtSignal(str)
    process_finished = pyqtSignal(bool)

    def __init__(self, collection_files, data_folder, config):
        super().__init__()
        self.collection_files = collection_files
        self.data_folder = data_folder
        self.config = config
        self.running = True

    def run(self):
        try:
            # 处理每个采集文件
            total_files = len(self.collection_files)
            for file_idx, collection_file in enumerate(self.collection_files):
                if not self.running:
                    break

                self.log_updated.emit(f"开始处理采集文件: {os.path.basename(collection_file)}")

                # 读取采集文件
                try:
                    collection_df = pd.read_excel(collection_file)
                    # 创建一个副本用于处理，避免修改原始数据
                    processed_df = collection_df.copy()
                except Exception as e:
                    self.log_updated.emit(f"读取采集文件失败: {str(e)}")
                    continue

                # 获取需要采集的字段配置
                collect_columns = self.config.get('collect_columns', [])
                if not collect_columns:
                    collect_columns = self.auto_detect_columns(collection_df)

                # 处理每个需要采集的字段
                column_count = len(collect_columns)
                for col_idx, column_config in enumerate(collect_columns):
                    if not self.running:
                        break

                    # 计算进度
                    progress = int((file_idx / total_files) * 100) + int(
                        (col_idx / (column_count * total_files)) * 100)
                    self.progress_updated.emit(progress)

                    # 确保配置是字典类型
                    if isinstance(column_config, tuple):
                        # 兼容旧版本的配置格式
                        data_file_name, target_key_col, target_data_col, key_col = column_config
                        target_column = key_col
                    else:
                        # 新版本的配置格式
                        data_file_name = column_config['data_file']
                        target_key_col = column_config['target_key_col']
                        target_data_col = column_config['target_data_col']
                        key_col = column_config['key_col']
                        target_column = column_config['data_col']
                    data_file_path = os.path.join(self.data_folder, data_file_name)

                    # 检查文件是否存在
                    if not os.path.exists(data_file_path):
                        self.log_updated.emit(f"数据文件不存在: {data_file_name}")
                        continue

                    # 读取数据文件
                    try:
                        if data_file_name.lower().endswith('.csv'):
                            data_df = pd.read_csv(data_file_path)
                        else:
                            data_df = pd.read_excel(data_file_path)
                    except Exception as e:
                        self.log_updated.emit(f"读取数据文件 {data_file_name} 失败: {str(e)}")
                        continue

                    # 检查采集文件的KEY列是否存在（使用列标）
                    key_index = self._column_to_index(key_col)
                    if key_index < 0 or key_index >= len(collection_df.columns):
                        self.log_updated.emit(f"采集文件中未找到列标: {key_col}")
                        continue

                    # 检查被采集文件的KEY列是否存在（使用列标）
                    data_key_index = self._column_to_index(target_key_col)
                    if data_key_index < 0 or data_key_index >= len(data_df.columns):
                        self.log_updated.emit(f"数据文件 {data_file_name} 中未找到列标: {target_key_col}")
                        continue

                    # 检查被采集文件的数据列是否存在（使用列标）
                    data_value_index = self._column_to_index(target_data_col)
                    if data_value_index < 0 or data_value_index >= len(data_df.columns):
                        self.log_updated.emit(f"数据文件 {data_file_name} 中未找到列标: {target_data_col}")
                        continue

                    # 创建关键字段到目标字段的映射（使用列标索引）
                    key_to_value = dict(zip(
                        data_df.iloc[:, data_key_index],
                        data_df.iloc[:, data_value_index]
                    ))
                    print(f'处理后的总字段：\n{key_to_value}')
                    # 填充采集文件（使用列标）
                    target_index = self._column_to_index(target_column)
                    if target_index >= len(processed_df.columns):
                        # 如果目标列不存在，则添加新列
                        processed_df.insert(target_index, f"新增列_{target_column}", None)

                    # 确保 key_to_value 映射正确
                    # 仅填充目标列中与当前 KEY 匹配的值，保留其他值
                    for idx in range(len(processed_df)):
                        key_value = processed_df.iloc[idx, key_index]
                        if key_value in key_to_value:
                            processed_df.iloc[idx, target_index] = key_to_value[key_value]
                    self.log_updated.emit(f"已完成列 {target_column} 的填充，共处理 {len(processed_df)} 条记录")

                # 保存处理后的采集文件
                try:
                    import datetime
                    timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
                    output_file = os.path.splitext(collection_file)[0] + f"_{timestamp}.xlsx"
                    # 确保数据正确写入
                    processed_df.to_excel(output_file, index=False, engine='openpyxl')
                    self.log_updated.emit(f"处理完成，结果已保存至: {output_file}")
                except Exception as e:
                    self.log_updated.emit(f"保存处理结果失败: {str(e)}")

            self.progress_updated.emit(100)
            self.log_updated.emit("所有文件处理完成")
            self.process_finished.emit(True)

        except Exception as e:
            self.log_updated.emit(f"处理过程中发生错误: {str(e)}")
            self.process_finished.emit(False)

    def _column_to_index(self, column):
        """将列标（A, B, C...）转换为索引（0, 1, 2...）"""
        if not column or not isinstance(column, str):
            return -1

        index = 0
        for char in column.upper():
            if 'A' <= char <= 'Z':
                index = index * 26 + (ord(char) - ord('A') + 1)
        return index - 1

    def _index_to_column(self, index):
        """将索引（0, 1, 2...）转换为列标（A, B, C...）"""
        if index < 0:
            return ""

        column = ""
        index += 1  # 转换为1-based索引
        while index > 0:
            index -= 1
            column = chr(ord('A') + (index % 26)) + column
            index = index // 26
        return column

    def auto_detect_columns(self, collection_df):
        """自动检测需要采集的列（基于列标）"""
        collect_columns = {}
        for idx in range(len(collection_df.columns)):
            col_name = str(collection_df.columns[idx])
            if col_name.lower().startswith('数据'):
                col_label = self._index_to_column(idx)
                field_name = col_name.replace('数据', '')
                collect_columns[col_label] = (f"文件{field_name}.xlsx", self._index_to_column(idx))
        return collect_columns

    def stop(self):
        """停止处理"""
        self.running = False